// 文件: GameManager.ts (修改后完整版)
import { _decorator, Component, Node, Prefab, instantiate, Vec3, v3, find, UITransform, tween, Sprite, Label } from 'cc';
import { EnemyMovement } from './EnemyMovement';
import { AStar } from './AStar';
import { cCollider } from './rvo/Collider';
import { CardDisplay } from './CardDisplay'; // 【新增】导入 CardDisplay 脚本
import { GameView } from './game/gameView/GameView';
import { Archer } from './Archer';
// import { Archer } from './Archer';

// 定义网格节点接口
export interface IGridNode {
    x: number;
    y: number;
    isObstacle: boolean;
    worldPos: Vec3;
}

const { ccclass, property } = _decorator;

@ccclass('GameManager')
export class GameManager extends Component {
    private static _instance: GameManager = null;
    public static get Instance(): GameManager { return this._instance; }

    // ===================================================================
    // 属性检查器设置
    // ===================================================================

    @property(Prefab)
    private rolePrefab: Prefab = null;

    @property({ type: Prefab, tooltip: "敌人的预制体" })
    private enemyPrefab: Prefab = null;

    @property({ type: Prefab, tooltip: "障碍物的预制体" })
    private obstaclePrefab: Prefab = null;

    @property({ type: [Node], tooltip: "引导玩家放置障碍物的位置标记节点数组" })
    private placementGuides: Node[] = [];

    // 【新增】对要解锁的弓兵卡牌的引用
    @property({ type: CardDisplay, group: "卡牌系统", tooltip: "需要解锁的弓兵卡牌" })
    private archerCard: CardDisplay = null;

    @property({ type: Node, group: "地图与寻路", tooltip: "用于计算网格尺寸和坐标转换的背景地图节点" })
    private mapNodeForGrid: Node = null;

    @property({ group: "地图与寻路", tooltip: "逻辑网格的尺寸" })
    private nodeSize: number = 25;

    @property({ type: Node, group: "地图与寻路", tooltip: "敌人出生横向区域的定位器" })
    private spawnLineLocator: Node = null;

    @property({ type: Node, group: "地图与寻路", tooltip: "敌人终点横向区域的定位器" })
    private endLineLocator: Node = null;

    @property({ group: "关卡设置", tooltip: "每一波生成的敌人纵队数量" })
    private columnCount: number = 10;

    @property({ group: "关卡设置", tooltip: "本关卡总共生成的敌人数量" })
    private totalEnemyCount: number = 150;

    @property({ group: "关卡设置", tooltip: "出兵的时间间隔（秒）" })
    private spawnInterval: number = 0.1;

    @property({ group: "关卡设置", tooltip: "玩家初始生命值" })
    private playerInitialHealth: number = 3;

    // ===================================================================
    // 私有变量
    // ===================================================================

    public allEnemies: Set<EnemyMovement> = new Set();
    private mapGrid: IGridNode[][] = [];
    private gridWidth: number = 0;
    private gridHeight: number = 0;
    private currentPlacementStep: number = 0;
    private guideTween: any = null;
    private timeSinceLastSpawn: number = 0;
    private enemiesSpawned: number = 0;
    private isGameWon: boolean = false;
    private obstacleSize: { width: number, height: number; } = { width: 0, height: 0 };
    private playerCurrentHealth: number = 0;

    // 【新增】解锁相关的变量
    private enemiesDefeatedCount: number = 0; // 已击败的敌人数量
    private readonly enemiesToUnlockCard: number = 2; // 解锁卡牌所需击败的敌人数量

    // ===================================================================
    // 生命周期回调
    // ===================================================================

    onLoad() {
        if (GameManager._instance) {
            console.error("GameManager 已经存在，不能重复创建！");
            this.destroy();
            return;
        }
        GameManager._instance = this;

        if (this.obstaclePrefab) {
            const tempObstacle = instantiate(this.obstaclePrefab);
            const uiTransform = tempObstacle.getComponent(UITransform);
            if (uiTransform) {
                this.obstacleSize.width = uiTransform.width;
                this.obstacleSize.height = uiTransform.height;
            }
            tempObstacle.destroy();
        }
        this.initGrid();
        this.playerCurrentHealth = this.playerInitialHealth;
    }

    start() {
        this.startPlacementGuide();

        this.init();
    }

    update(dt: number) {
        cCollider.inst.update(dt);
        this.updateSpawn(dt);
    }

    private init(): void {
        this.addRole();
    }

    public addRole(): void {
        const node: Node = instantiate(this.rolePrefab);
        this.node.addChild(node);
    }

    // ===================================================================
    // 核心游戏逻辑
    // ===================================================================

    /**
     * 当基地受到伤害时调用
     * @param damage 伤害值
     */
    public takeDamage(damage: number) {
        if (this.isGameWon) return;
        this.playerCurrentHealth -= damage;
        console.log(`基地受到 ${ damage } 点伤害，剩余生命: ${ this.playerCurrentHealth }`);
        if (this.playerCurrentHealth <= 0) {
            this.playerCurrentHealth = 0;
            console.log("游戏失败！");
            // 在这里可以实现游戏失败的逻辑，比如暂停游戏，弹出失败面板
        }
    }

    /**
     * 当一个敌人被击败时调用
     * @param enemyScript 被击败的敌人脚本实例
     */
    public onEnemyDefeated(enemyScript: EnemyMovement) {
        if (!enemyScript) return;

        if (this.allEnemies.has(enemyScript)) {
            this.allEnemies.delete(enemyScript);
        }

        // 增加击败计数，并检查是否满足解锁条件
        this.enemiesDefeatedCount++;
        console.log(`击败敌人总数: ${ this.enemiesDefeatedCount }`);

        if (this.enemiesDefeatedCount === this.enemiesToUnlockCard) {
            console.log("满足解锁条件！准备解锁弓兵卡牌。");
            if (this.archerCard) {
                this.archerCard.unlockCard();
            }
        }

        // 检查游戏胜利条件
        if (this.enemiesSpawned >= this.totalEnemyCount && this.allEnemies.size === 0) {
            this.isGameWon = true;
            console.log("恭喜通关！所有敌人都已被消灭！");
        }
    }

    // ... (所有其他函数，如 initGrid, placeObstacleAt, spawnEnemyGroup 等，都保持不变)
    // ===================================================================
    // 初始化
    // ===================================================================
    private initGrid() {
        if (!this.mapNodeForGrid) { console.error("mapNodeForGrid 未设置！"); return; }
        const uiTransform = this.mapNodeForGrid.getComponent(UITransform);
        const scale = this.mapNodeForGrid.getScale();
        const mapWidth = uiTransform.width * scale.x;
        const mapHeight = uiTransform.height * scale.y;
        this.gridWidth = Math.floor(mapWidth / this.nodeSize);
        this.gridHeight = Math.floor(mapHeight / this.nodeSize);
        this.mapGrid = [];
        for (let x = 0; x < this.gridWidth; x++) {
            this.mapGrid[x] = [];
            for (let y = 0; y < this.gridHeight; y++) {
                const localX = x * this.nodeSize + this.nodeSize / 2 - mapWidth * uiTransform.anchorX;
                const localY = y * this.nodeSize + this.nodeSize / 2 - mapHeight * uiTransform.anchorY;
                const worldPos = uiTransform.convertToWorldSpaceAR(v3(localX, localY, 0));
                this.mapGrid[x][y] = { x, y, isObstacle: false, worldPos };
            }
        }
        console.log(`网格初始化完成: ${ this.gridWidth }x${ this.gridHeight }`);
    }

    // ===================================================================
    // 引导放置逻辑
    // ===================================================================
    private startPlacementGuide() {
        if (this.guideTween) this.guideTween.stop();
        if (this.currentPlacementStep >= this.placementGuides.length) {
            console.log("所有引导障碍物已放置完毕！");
            return;
        }
        for (let i = 0; i < this.placementGuides.length; i++) {
            this.placementGuides[i].active = (i === this.currentPlacementStep);
        }
        const currentGuide = this.placementGuides[this.currentPlacementStep];
        const guideSprite = currentGuide.getComponent(Sprite);
        if (!guideSprite) { console.error(`引导节点 ${ currentGuide.name } 上缺少 Sprite 组件！`); return; }
        currentGuide.setScale(1, 1, 1);
        this.guideTween = tween(currentGuide)
            .to(0.5, { scale: v3(1.1, 1.1, 1) })
            .to(0.5, { scale: v3(1, 1, 1) })
            .union().repeatForever().start();
        currentGuide.once(Node.EventType.TOUCH_START, () => this.placeObstacleAt(currentGuide));
    }

    private placeObstacleAt(guideNode: Node) {
        if (this.guideTween) this.guideTween.stop();
        guideNode.setScale(1, 1, 1);
        guideNode.active = false;

        const obstacle = instantiate(this.obstaclePrefab);
        GameView.Instance.node.addChild(obstacle);
        const obstacleWorldPos = guideNode.worldPosition;
        obstacle.setWorldPosition(obstacleWorldPos);

        const halfWidth = this.obstacleSize.width / 2;
        const halfHeight = this.obstacleSize.height / 2;

        for (let dx = -halfWidth; dx <= halfWidth; dx += this.nodeSize / 2) {
            for (let dy = -halfHeight; dy <= halfHeight; dy += this.nodeSize / 2) {
                const checkPos = v3(obstacleWorldPos.x + dx, obstacleWorldPos.y + dy, 0);
                const gridNode = this.getGridNodeFromWorldPos(checkPos);
                if (gridNode && !gridNode.isObstacle) {
                    gridNode.isObstacle = true;
                }
            }
        }

        console.log(`在 ${ guideNode.name } 位置放置了障碍物，并标记了其覆盖的所有网格`);
        this.updateAllEnemyPaths();
        this.currentPlacementStep++;
        this.startPlacementGuide();
    }

    // ===================================================================
    // 出兵逻辑
    // ===================================================================
    private updateSpawn(dt: number) {
        if (this.isGameWon) return;
        if (this.enemiesSpawned < this.totalEnemyCount) {
            this.timeSinceLastSpawn += dt;
            if (this.timeSinceLastSpawn >= this.spawnInterval) {
                this.spawnEnemyGroup();
                this.timeSinceLastSpawn = 0;
            }
        }
    }

    private spawnEnemyGroup() {
        for (let i = 0; i < this.columnCount; i++) {
            if (this.enemiesSpawned < this.totalEnemyCount) {
                this.spawnSingleEnemy(i);
                this.enemiesSpawned++;
            }
        }
    }

    private spawnSingleEnemy(columnIndex: number) {
        if (!this.enemyPrefab || !this.spawnLineLocator || !this.endLineLocator) return;
        const horizontalPercent = (columnIndex + 0.5) / this.columnCount;
        const spawnLineWidth = this.spawnLineLocator.getComponent(UITransform).width * this.spawnLineLocator.getScale().x;
        const spawnLineCenter = this.spawnLineLocator.worldPosition;
        const spawnOffsetX = (horizontalPercent - 0.5) * spawnLineWidth;
        const spawnPos = v3(spawnLineCenter.x + spawnOffsetX, spawnLineCenter.y, 0);
        const endLineWidth = this.endLineLocator.getComponent(UITransform).width * this.endLineLocator.getScale().x;
        const endLineCenter = this.endLineLocator.worldPosition;
        const endOffsetX = (horizontalPercent - 0.5) * endLineWidth;
        const endPos = v3(endLineCenter.x + endOffsetX, endLineCenter.y, 0);
        const startNode = this.getGridNodeFromWorldPos(spawnPos);
        const endNode = this.getGridNodeFromWorldPos(endPos);
        if (!startNode || !endNode) { return; }
        const path = AStar.findPath(startNode, endNode, this.mapGrid);
        if (!path) { return; }
        const worldPath = path.map(node => node.worldPos);
        const enemyNode = instantiate(this.enemyPrefab);
        GameView.Instance.node.addChild(enemyNode);
        enemyNode.setWorldPosition(spawnPos);
        const enemyScript = enemyNode.getComponent(EnemyMovement);
        if (enemyScript) {
            enemyScript.gameManager = this;
            this.allEnemies.add(enemyScript);
            enemyScript.setPath(worldPath);
        }
    }

    // ===================================================================
    // 工具函数
    // ===================================================================
    private updateAllEnemyPaths() {
        console.log("检测到障碍物变化，更新所有敌人路径...");
        const endLineUIT = this.endLineLocator.getComponent(UITransform);
        const endLineWidth = endLineUIT.width * this.endLineLocator.getScale().x;
        const endLineWorldPos = this.endLineLocator.worldPosition;
        const endLineLeftEdgeX = endLineWorldPos.x - endLineWidth * endLineUIT.anchorX;
        for (const enemy of this.allEnemies) {
            if (enemy && enemy.node.isValid) {
                const enemyStartNode = this.getGridNodeFromWorldPos(enemy.node.worldPosition);
                const enemyWorldX = enemy.node.worldPosition.x;
                const horizontalPercent = (enemyWorldX - endLineLeftEdgeX) / endLineWidth;
                const columnIndex = Math.floor(horizontalPercent * this.columnCount);
                const endOffsetX = ((columnIndex + 0.5) / this.columnCount - 0.5) * endLineWidth;
                const endPos = v3(endLineWorldPos.x + endOffsetX, endLineWorldPos.y, 0);
                const enemyEndNode = this.getGridNodeFromWorldPos(endPos);
                if (enemyStartNode && enemyEndNode) {
                    const path = AStar.findPath(enemyStartNode, enemyEndNode, this.mapGrid);
                    if (path) {
                        const worldPath = path.map(node => node.worldPos);
                        enemy.setPath(worldPath);
                    } else {
                        console.log(`敌人 ${ enemy.node.uuid } 被困住了！`);
                    }
                }
            }
        }
    }

    private getGridNodeFromWorldPos(worldPos: Vec3): IGridNode | null {
        const uiTransform = this.mapNodeForGrid.getComponent(UITransform);
        if (!uiTransform) return null;
        const localPos = uiTransform.convertToNodeSpaceAR(worldPos);
        const scale = this.mapNodeForGrid.getScale();
        const mapWidth = uiTransform.width * scale.x;
        const mapHeight = uiTransform.height * scale.y;
        const x = Math.floor((localPos.x + mapWidth * uiTransform.anchorX) / this.nodeSize);
        const y = Math.floor((localPos.y + mapHeight * uiTransform.anchorY) / this.nodeSize);
        if (x >= 0 && x < this.gridWidth && y >= 0 && y < this.gridHeight) {
            return this.mapGrid[x][y];
        }
        return null;
    }
}
